package thread.base;

import java.util.concurrent.*;

/**
 * 创建线程的几种方式，但是本质上只能说一种
 */
public class ThreadCreate {
    // 继承Thread类的方式
    static class MyThread extends Thread {

        @Override
        public void run() {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("通过继承Thread类创建的线程正在运行" + Thread.currentThread().getName());
        }
    }

    // 实现Runnable接口的方式
    static class MyRunnable implements Runnable {
        @Override
        public void run() {
            System.out.println("通过实现Runnable接口创建的线程正在运行" + Thread.currentThread().getName());
        }
    }

    // 实现Callable接口的方式
    static class MyCallable implements Callable<String> {
        @Override
        public String call() throws Exception {
            return "通过实现Callable接口创建的线程正在运行" + Thread.currentThread().getName();
        }
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        // 主线程信息
        Thread mainThread = Thread.currentThread();
        System.out.println("主线程运行中: " + mainThread.getName());

        // 1、使用继承Thread类的方式创建线程
        MyThread thread1 = new MyThread();
        thread1.start();

        // 2、使用Runnable接口创建线程
        MyRunnable runnable = new MyRunnable();
        Thread thread2 = new Thread(runnable);
        thread2.start();

        // 3、使用Callable接口配合FutureTask创建线程
        MyCallable callable = new MyCallable();
        FutureTask<String> futureTask = new FutureTask<>(callable);
        Thread thread3 = new Thread(futureTask);
        thread3.start();
        // 获取Callable返回结果
        System.out.println(futureTask.get());

        // 4. 使用线程池创建线程
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        executorService.submit(() -> System.out.println("通过线程池提交的Runnable任务正在运行"));
        Future<String> future = executorService.submit(callable);
        System.out.println(future.get());

        // 5. 使用CompletableFuture实现异步任务
        CompletableFuture<Void> future1 = CompletableFuture.runAsync(() ->
                System.out.println("通过CompletableFuture运行的Runnable任务正在运行" + Thread.currentThread().getName())
        );
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() ->
                {
                    System.out.println("通过CompletableFuture运行的Callable任务正在运行" + Thread.currentThread().getName());
                    return "成功";
                }
        );
    }
}
